package com.transcom.locationprovider;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainActivity extends Activity implements View.OnClickListener {
    private static final String TAG = "MainActivity";
    public static final int REFRESH_CONNECTED = 2;
    public static final int REFRESH_CONNECT_FAIL = 4;
    public static final int REFRESH_CONNECTING = 5;

    public static String BlueToothAddress = "";
    public static String BlueToothName = "";
    public static boolean isOpen = false;
    private LocationManager locationManager;
    private Location mLocation = new Location("");
    private ListView mListView;
    private ArrayList<BlueToothDeviceInfoEntity> list;
    private Button seachButton, send;
    private BlueToothDeviceInfoAdapter mAdapter;
    private Context mContext;
    private TextView tLongitude;
    private TextView tLatitude;
    private TextView tState;
    private TextView tvAltitude;
    private TextView tvTime;
    private int connectIndex = 0;
    private BluetoothSocket socket = null;
    private BluetoothDevice device = null;
    // 取得默认的蓝牙适配器
    private BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();
    private boolean isBTOpen;
    Timer timer = new Timer();
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case REFRESH_CONNECTING:
                    tState.setText((String) msg.obj);
                    break;
                case REFRESH_CONNECT_FAIL:
                    tState.setText((String) msg.obj);
                    break;
                case REFRESH_CONNECTED:
                    tState.setText((String) msg.obj);
                    BlueToothDeviceInfoEntity item = list.get(connectIndex);
                    item.mState = true;
                    list.set(connectIndex, item);
                    mAdapter.notifyDataSetChanged();

                    // 发送位置信息
                    timer.schedule(new TimerTask() {
                        @TargetApi(Build.VERSION_CODES.KITKAT)
                        @Override
                        public void run() {
                            sendMessageHandle(mLocation.getLatitude() + "," + mLocation.getLongitude() + "," + mLocation.getAltitude() + "," + mLocation.getTime() + ";");//
                        }
                    }, 100, 1000);
                    break;
            }
            super.handleMessage(msg);
        }
    };


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        init();
        // Register for broadcasts when a device is discovered
        IntentFilter discoveryFilter = new IntentFilter();
        discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);
        discoveryFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        discoveryFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        discoveryFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
        discoveryFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);

        this.registerReceiver(mReceiver, discoveryFilter);
        // 获取地理位置管理器
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        // 获取所有可用的位置提供器
        List<String> providers = locationManager.getProviders(true);
        if ((providers.contains(LocationManager.NETWORK_PROVIDER) == false) && (providers.contains(LocationManager.GPS_PROVIDER) == false)) {//
            Toast.makeText(this, "GPS OFF", Toast.LENGTH_SHORT).show();
        }
        // 监视地理位置变化
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "该应用没有设置相关权限", Toast.LENGTH_LONG).show();
        }
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, gpsLocationListener);//
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 2000, 10, netLocationListener);//

        //
//        timer.schedule(new TimerTask() {
//            @TargetApi(Build.VERSION_CODES.M)
//            @Override
//            public void run() {
//                if (socket != null) {
//                    Log.e(TAG, "蓝牙连接状态: " + socket.isConnected());
//                }
//
//            }
//        }, 2000, 2000);
    }

    private void init() {
        tLatitude = (TextView) findViewById(R.id.latitude);
        tLongitude = (TextView) findViewById(R.id.longitude);
        tvAltitude = (TextView) findViewById(R.id.tv_altitude);
        tState = (TextView) findViewById(R.id.state);
        list = new ArrayList<BlueToothDeviceInfoEntity>();
        mAdapter = new BlueToothDeviceInfoAdapter(this, list);
        mListView = (ListView) findViewById(android.R.id.list);
        mListView.setAdapter(mAdapter);
        mListView.setFastScrollEnabled(true);
        mListView.setOnItemClickListener(mDeviceClickListener);
        seachButton = (Button) findViewById(R.id.startSearch);
        send = (Button) findViewById(R.id.send);
        tvTime = (TextView) findViewById(R.id.tv_time);
        seachButton.setOnClickListener(this);
        send.setOnClickListener(this);

    }


    private void updateLocation() {
        String strLongitude;
        String strLatitude;
        if (mLocation != null) {
            strLongitude = mContext.getString(R.string.Longitude).toString() + String.format("%.7f°", mLocation.getLongitude());//
            strLatitude = mContext.getString(R.string.Latitude).toString() + String.format("%.7f°", mLocation.getLatitude());//
        } else {
            strLongitude = mContext.getString(R.string.Longitude).toString();
            strLatitude = mContext.getString(R.string.Latitude).toString();
        }
        tLongitude.setText(strLongitude);
        tLatitude.setText(strLatitude);
        tvAltitude.setText("海拔:" + mLocation.getAltitude());
        tvTime.setText("时间：" + mLocation.getTime());
    }


    /**
     * LocationListern监听器 参数：地理位置提供器、监听位置变化的时间间隔、位置变化的距离间隔、LocationListener监听器
     */
    LocationListener gpsLocationListener = new LocationListener() {
        @Override
        public void onStatusChanged(String provider, int status, Bundle arg2) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }

        @Override
        public void onLocationChanged(Location location) {
            // 如果位置发生变化,重新显示
            mLocation.set(location);
            updateLocation();
            sendMessageHandle(mLocation.getLatitude() + "," + mLocation.getLongitude() + "," + mLocation.getAltitude() + "," + mLocation.getTime() + ";");//
        }
    };

    LocationListener netLocationListener = new LocationListener() {

        @Override
        public void onStatusChanged(String provider, int status, Bundle arg2) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }

        @Override
        public void onLocationChanged(Location location) {
            // 如果位置发生变化,重新显示
            mLocation.set(location);
            updateLocation();
            sendMessageHandle(mLocation.getLatitude() + "," + mLocation.getLongitude() + "," + mLocation.getAltitude() + "," + mLocation.getTime() + ";");//
        }
    };

    // 蓝牙发送数据
    private synchronized void sendMessageHandle(String msg) {
        if (socket == null) {
            Toast.makeText(mContext, R.string.not_connect, Toast.LENGTH_SHORT).show();
            return;
        }
        try {
            Log.e(TAG, "sendMessageHandle: " + mLocation.getLatitude() + "," + mLocation.getLongitude() + "," + mLocation.getAltitude() + ";");
            OutputStream out = socket.getOutputStream();
            out.write(msg.getBytes());
//            out.flush();
//            out.close();
        } catch (Exception e) {

        }
    }

    /**
     * item 单击事件
     */
    private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
        public void onItemClick(AdapterView<?> av, View v, final int index, long arg3) {
            BlueToothDeviceInfoEntity item = list.get(index);
            String[] str = item.mName.split("\n");
            BlueToothName = str[0];
            BlueToothAddress = str[1];
            AlertDialog.Builder StopDialog = new AlertDialog.Builder(mContext);
            StopDialog.setTitle(R.string.connecte);// 标题
            StopDialog.setMessage(item.mName);
            StopDialog.setPositiveButton(R.string.connecte,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            isBTOpen = mBtAdapter.isEnabled();
                            if (isBTOpen) {
                                mBtAdapter.cancelDiscovery();
                                seachButton.setText(R.string.research);
                                device = mBtAdapter.getRemoteDevice(BlueToothAddress);
                                new clientThread().start();
                                connectIndex = index;
                            } else {
                                Toast.makeText(MainActivity.this, R.string.search_tip, Toast.LENGTH_SHORT).show();//
                            }
                        }
                    });
            StopDialog.setNegativeButton(R.string.cancel,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            BlueToothAddress = null;
                        }
                    });
            StopDialog.show();
        }
    };

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Get the BluetoothDevice object from the Intent
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);//
                list.add(new BlueToothDeviceInfoEntity(device.getName() + "\n" + device.getAddress(), false));//
                mAdapter.notifyDataSetChanged();
                mListView.setSelection(list.size() - 1);
                Log.e(TAG, "onReceive: " + BluetoothDevice.ACTION_FOUND);
            } else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
                Log.e(TAG, "onReceive: " + BluetoothDevice.ACTION_ACL_CONNECTED);
            } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
                Log.e(TAG, "onReceive: " + BluetoothDevice.ACTION_ACL_DISCONNECTED);
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                setProgressBarIndeterminateVisibility(false);
                if (mListView.getCount() == 0) {
                    Toast.makeText(MainActivity.this, R.string.not_find, Toast.LENGTH_SHORT).show();//
                }
                seachButton.setText(R.string.research);
                Log.e(TAG, "onReceive: " + BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                Log.e(TAG, "onReceive: " + BluetoothAdapter.ACTION_STATE_CHANGED);
                isBTOpen = mBtAdapter.isEnabled();
            } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
                Log.e(TAG, "onReceive: " + BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
            }
        }
    };

    // 开启线程作为客户端
    private class clientThread extends Thread {
        @TargetApi(Build.VERSION_CODES.M)
        public void run() {
            try {
                // 创建一个Socket连接：只需要服务器在注册时的UUID号
                socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));//
                // 连接中...
                Message msg2 = Message.obtain();
                msg2.obj = mContext.getResources().getString(R.string.connecting) + MainActivity.BlueToothName;
                msg2.what = REFRESH_CONNECTING;
                mHandler.sendMessage(msg2);
                socket.connect();
                Log.e(TAG, "run:connecting ");
                // 连接ok
                Message msg3 = new Message();
                msg3.what = REFRESH_CONNECTED;
                msg3.obj = mContext.getResources().getString(R.string.connected);
                mHandler.sendMessage(msg3);
                Log.e(TAG, "run: connected");
                Log.e(TAG, "蓝牙连接状态: " + socket.isConnected());
            } catch (Exception e) {
                //连接异常
                Message msg = Message.obtain();
                msg.obj = mContext.getResources().getString(R.string.exception);
                msg.what = REFRESH_CONNECT_FAIL;
                mHandler.sendMessage(msg);
                Log.e(TAG, "run: " + mContext.getResources().getString(R.string.exception));
            }
        }
    }

    @Override
    protected void onDestroy() {
        if (socket != null)
            Log.e(TAG, "onDestroy: " + socket.isConnected());
        super.onDestroy();
        unregisterReceiver(mReceiver);
        if (mBtAdapter != null) {
            mBtAdapter.cancelDiscovery();
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (device != null) {
            device = null;
        }
        if (timer != null) {
            timer.cancel();
        }

    }


    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.startSearch:
                startSearchBluetooth();
                break;
            case R.id.send:
                sendMessageHandle(mLocation.getLatitude() + "," + mLocation.getLongitude() + "," + mLocation.getAltitude() + "," + mLocation.getTime() + ";");//
                break;
            default:
                break;
        }

    }


    /**
     * 搜索蓝牙、打开
     */
    private void startSearchBluetooth() {
        isBTOpen = mBtAdapter.isEnabled();
        if (isBTOpen) {
            if (mBtAdapter.isDiscovering()) {
                mBtAdapter.cancelDiscovery();
                seachButton.setText(R.string.research);
            } else {
                list.clear();
                mAdapter.notifyDataSetChanged();
                // 开始搜索
                mBtAdapter.startDiscovery();
                seachButton.setText(R.string.stop_search);
            }
        } else {
            mBtAdapter.enable();
            startSearchBluetooth();
        }
    }
}
